
#################################################################################################

#  Description: Generating Tables and Figures from APPENDIX of Fleming, Thomas G. (Forthcoming) 
#               'Partisan Dealignment and Personal Vote-Seeking in Parliamentary Behaviour', 
#               Political Studies.
#  Author:      Thomas G. Fleming
#  Date:        25/08/2020
#  Note:        Requires file "MP_data.csv" to be saved in same folder

#################################################################################################

rm(list=ls())

library(stargazer)
library(coefplot)
library(DescTools)  # for PseudoR2
library(MASS)       # for glm.nb
library(lme4)       # for lmer()
library(ggpubr)     # for ggscatter
library(clusterSEs) # for cluster.bs.glm()

library(rstudioapi)
current_path <- getActiveDocumentContext()$path
setwd(dirname(current_path))

####################################################
# Loading data and generating additional variables #
####################################################

  # loads data

  data <- read.csv("./MP_data.csv")

  # puts share margin on same scale as partisanship variable
  
  data$share_margin <- 100*data$voteshare_margin 
  
  # creates indicator of whether challenger was from third party
  
  data$thirdparty.challenge <- ifelse((data$challenger == "Conservative" | data$challenger == "Labour"), 0, 1)
  
  # creates measure of the age at which MPs were first elected to parliament
  
  data$age.elected <- data$first_elected - data$born
  
  # creates combined measure of ten minute bill proposals
  
  data$PMBs.tenminute.combined <- data$PMBs.tenminute.negatived + data$PMBs.tenminute.permitted
  
  # limiting dataset to only subset of MPs
  
  reduced.data <- data[(is.na(data$by_election_out) == TRUE) &                                     # drops those who left at by-elections
                         (is.na(data$by_election_in) == TRUE) &                                    # drops those who arrive at by-elections
                         (is.na(data$party_switch1) == TRUE) &                                     # drops those who switch parties
                         (is.na(data$speakers) == TRUE) &                                          # drops (deputy) speakers
                         (is.na(data$minister) == TRUE) &                                          # drops ministers
                         (is.na(data$whip) == TRUE) &                                              # drops whips
                         (data$nation != "Northern Ireland") &                                     # drops NI constituencies
                         (data$retired != "Not applicable - by-election pending (death)") &        # drops those who died near term's end
                         (data$retired != "Not applicable - by-election pending (resignation)") &  # drops those who resigned but no by-election
                         ((data$party == "Labour") | (data$party == "Conservative")),]             # drops third party MPs 
  
#############################################################
# Table B1 - Count models of MPs' bill proposals, 1964-2017 #
#############################################################
  
  # Model B1 - Repeating Model 4 for all bills, using negative binomial regression
  
  model.4.all.negbin <- glm.nb(PMBs.total ~ 
                                 partisanship_verystrong*share_margin + 
                                 sitting_days + 
                                 gov + 
                                 retired + 
                                 thirdparty.challenge +
                                 age.elected*share_margin +
                                 party_polarisation*share_margin, 
                               data = reduced.data)
  model.4.all.negbin.R2 <- PseudoR2(model.4.all.negbin, which = "McFadden")
  
  # Model B2 - Repeating Model 4 for presentation bills, using negative binomial regression
  
  model.4.presentation.negbin <- glm.nb(PMBs.presentation ~ 
                                          partisanship_verystrong*share_margin + 
                                          sitting_days + 
                                          gov + 
                                          retired + 
                                          thirdparty.challenge +
                                          age.elected*share_margin +
                                          party_polarisation*share_margin, 
                                        data = reduced.data)
  model.4.presentation.negbin.R2 <- PseudoR2(model.4.presentation.negbin, which = "McFadden")
  
  # Model B3 - Repeating Model 4 for ballot bills, using poisson regression
  
  model.4.ballot.poisson <- glm(PMBs.ballot ~
                                  partisanship_verystrong*share_margin + 
                                  sitting_days + 
                                  gov + 
                                  retired + 
                                  thirdparty.challenge +
                                  age.elected*share_margin +
                                  party_polarisation*share_margin, 
                                family = "poisson",
                                data = reduced.data)
  model.4.ballot.poisson.R2 <- PseudoR2(model.4.ballot.poisson, which = "McFadden")
  
  # Model B4 - Repeating Model 4 for ten minute rule bills, using negative binomial regression
  
  model.4.tenminute.negbin <- glm.nb(PMBs.tenminute.combined ~
                                       partisanship_verystrong*share_margin + 
                                       sitting_days + 
                                       gov + 
                                       retired + 
                                       thirdparty.challenge +
                                       age.elected*share_margin +
                                       party_polarisation*share_margin, 
                                     data = reduced.data)
  model.4.tenminute.negbin.R2 <- PseudoR2(model.4.tenminute.negbin, which = "McFadden")
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship_verystrong", "share_margin", "partisanship_verystrong:share_margin", "Constant")
  
  stargazer(model.4.all.negbin, 
            model.4.presentation.negbin, 
            model.4.ballot.poisson, 
            model.4.tenminute.negbin, 
            type = "html",
            title = "Count models of MPs' bill proposals, 1964-2017",
            out = "./tableB1.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Constant"),
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                             c("Observations", "5,015", "5,015", "5,015", "5,015"),
                             c("Pseudo R\\textsuperscript{2}", 
                               round(model.4.all.negbin.R2, digits = 3), 
                               round(model.4.presentation.negbin.R2, digits = 3),
                               round(model.4.ballot.poisson.R2, digits = 3),
                               round(model.4.tenminute.negbin.R2, digits = 3))),
            omit.stat = c("n", "ll", "theta", "aic"),
            no.space = TRUE,
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals (by type)}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B1)", "(B2)", "(B3)", "(B4)"),
            font.size = "small")
  
#############################################################################
# Table B2 - OLS regression of MPs' bill proposals (all parties), 1964-2017 #
#############################################################################
  
  # Generating subset of data to include backbenchers from all parties
  
  all.parties <- data[(is.na(data$by_election_out) == TRUE) &                                     # drops those who left at by-elections
                        (is.na(data$by_election_in) == TRUE) &                                    # drops those who arrive at by-elections
                        (is.na(data$party_switch1) == TRUE) &                                     # drops those who switch parties
                        (is.na(data$speakers) == TRUE) &                                          # drops (deputy) speakers
                        (is.na(data$minister) == TRUE) &                                          # drops ministers
                        (is.na(data$whip) == TRUE) &                                              # drops whips
                        (data$nation != "Northern Ireland") &                                     # drops NI constituencies
                        (data$retired != "Not applicable - by-election pending (death)") &        # drops those who died near term's end
                        (data$retired != "Not applicable - by-election pending (resignation)"),]  # drops those who resigned but no by-election
  
  # Model B5 - Repeating Model 4 for all bills, including all parties' backbenchers
  
  model.4.all.ols.allparties <- lm(PMBs.total ~ 
                                     partisanship_verystrong*share_margin + 
                                     sitting_days + 
                                     gov + 
                                     retired + 
                                     thirdparty.challenge +
                                     age.elected*share_margin +
                                     party_polarisation*share_margin, 
                                   data = all.parties)
  
  # Model B6 - Repeating Model 4 for presentation bills, including all parties' backbenchers
  
  model.4.presentation.ols.allparties <- lm(PMBs.presentation ~
                                              partisanship_verystrong*share_margin +
                                              sitting_days +
                                              gov +
                                              retired +
                                              thirdparty.challenge +
                                              age.elected*share_margin +
                                              party_polarisation*share_margin,
                                            data = all.parties)
  
  # Model B7 - Repeating Model 4 for ballot bills, including all parties' backbenchers
  
  model.4.ballot.ols.allparties <- lm(PMBs.ballot ~
                                        partisanship_verystrong*share_margin +
                                        sitting_days +
                                        gov +
                                        retired +
                                        thirdparty.challenge +
                                        age.elected*share_margin +
                                        party_polarisation*share_margin,
                                      data = all.parties)
  
  # Model B8 - Repeating Model 4 for ten minute rule bills, including all parties' backbenchers
  
  model.4.tenminute.ols.allparties <- lm(PMBs.tenminute.combined ~
                                           partisanship_verystrong*share_margin +
                                           sitting_days +
                                           gov +
                                           retired +
                                           thirdparty.challenge +
                                           age.elected*share_margin +
                                           party_polarisation*share_margin,
                                         data = all.parties)
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship_verystrong", "share_margin", "partisanship_verystrong:share_margin", "Constant")
  
  stargazer(model.4.all.ols.allparties ,
            model.4.presentation.ols.allparties,
            model.4.ballot.ols.allparties, 
            model.4.tenminute.ols.allparties, 
            type = "html",
            title = "OLS regression of MPs' bill proposals (all parties), 1964-2017",
            out = "./tableB2.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Constant"),
            keep.stat = c("rsq","n"),
            no.space = TRUE,
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark")),
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals (by type)}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B5)", "(B6)", "(B7)", "(B8)"),
            font.size = "small")
  
#################################################################################################
# Table B3 - OLS regression of MPs' bill proposals (incl. 'fairly strong' partisans), 1964-2017 #
#################################################################################################  
  
  # Creating variable that combines very strong and fairly strong partisanship
  
  reduced.data$partisanship.combined <- reduced.data$partisanship_verystrong + reduced.data$partisanship_fairlystrong
  
  # Model B9 - Repeating Model 4 for all bills, using broader partisanship measure
  
  model.4.all.ols.broaderpartisanship <- lm(PMBs.total ~ 
                                              partisanship.combined*share_margin + 
                                              sitting_days + 
                                              gov + 
                                              retired + 
                                              thirdparty.challenge +
                                              age.elected*share_margin +
                                              party_polarisation*share_margin, 
                                            data = reduced.data)
  
  # Model B10 - Repeating Model 4 for presentation bills, using broader partisanship measure
  
  model.4.presentation.ols.broaderpartisanship <- lm(PMBs.presentation ~
                                                       partisanship.combined*share_margin +
                                                       sitting_days +
                                                       gov +
                                                       retired +
                                                       thirdparty.challenge +
                                                       age.elected*share_margin +
                                                       party_polarisation*share_margin,
                                                     data = reduced.data)
  
  # Model B11 - Repeating Model 4 for ballot bills, using broader partisanship measure
  
  model.4.ballot.ols.broaderpartisanship <- lm(PMBs.ballot ~
                                                 partisanship.combined*share_margin +
                                                 sitting_days +
                                                 gov +
                                                 retired +
                                                 thirdparty.challenge +
                                                 age.elected*share_margin +
                                                 party_polarisation*share_margin,
                                               data = reduced.data)
  
  # Model B12 - Repeating Model 4 for ten minute rule bills, using broader partisanship measure
  
  model.4.tenminute.ols.broaderpartisanship <- lm(PMBs.tenminute.combined ~
                                                    partisanship.combined*share_margin +
                                                    sitting_days +
                                                    gov +
                                                    retired +
                                                    thirdparty.challenge +
                                                    age.elected*share_margin +
                                                    party_polarisation*share_margin,
                                                  data = reduced.data)
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship.combined", "share_margin", "partisanship.combined:share_margin", "Constant")
  
  stargazer(model.4.all.ols.broaderpartisanship,
            model.4.presentation.ols.broaderpartisanship,
            model.4.ballot.ols.broaderpartisanship, 
            model.4.tenminute.ols.broaderpartisanship, 
            type = "html",
            title = "OLS model of MPs' bill proposals (incl. `fairly strong' partisans), 1964-2017",
            out = "./tableB3.htm",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Constant"),
            keep.stat = c("n", "rsq"),
            no.space = TRUE,
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark")),
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals (by type)}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B9)", "(B10)", "(B11)", "(B12)"),
            font.size = "small")
  
#####################################################################################
# Table B4 - OLS regression of MPs' bill proposals (additional controls), 1964-2017 #
#####################################################################################
  
  # Generating additional variables
  
  reduced.data$PPS.binary <- ifelse(is.na(reduced.data$PPS) == FALSE, 1, 0)
  
  reduced.data$log.seniority <- log((reduced.data$yr - reduced.data$first_elected)+1)
  
  # Model B13 - Repeating Model 4 for all bills, with extra controls
  
  model.4.all.ols.ctrls <- lm(PMBs.total ~ 
                                partisanship_verystrong*share_margin + 
                                sitting_days + 
                                gov + 
                                retired + 
                                thirdparty.challenge +
                                age.elected*share_margin +
                                party_polarisation*share_margin +
                                sex +
                                PPS.binary +
                                nation +
                                party +
                                log.seniority, 
                              data = reduced.data)
  
  # Model B14 - Repeating Model 4 for presentation bills, with extra controls
  
  model.4.presentation.ols.ctrls <- lm(PMBs.presentation ~
                                         partisanship_verystrong*share_margin +
                                         sitting_days +
                                         gov +
                                         retired +
                                         thirdparty.challenge +
                                         age.elected*share_margin +
                                         party_polarisation*share_margin +
                                         sex +
                                         PPS.binary +
                                         nation +
                                         party +
                                         log.seniority, 
                                       data = reduced.data)
  
  # Model B15 - Repeating Model 4 for ballot bills, with extra controls
  
  model.4.ballot.ols.ctrls <- lm(PMBs.ballot ~
                                   partisanship_verystrong*share_margin +
                                   sitting_days +
                                   gov +
                                   retired +
                                   thirdparty.challenge +
                                   age.elected*share_margin +
                                   party_polarisation*share_margin +
                                   sex +
                                   PPS.binary +
                                   nation +
                                   party +
                                   log.seniority, 
                                 data = reduced.data)
  
  # Model B16 - Repeating Model 4 for ten minute rule bills, with extra controls
  
  model.4.tenminute.ols.ctrls <- lm(PMBs.tenminute.combined ~
                                      partisanship_verystrong*share_margin +
                                      sitting_days +
                                      gov +
                                      retired +
                                      thirdparty.challenge +
                                      age.elected*share_margin +
                                      party_polarisation*share_margin +
                                      sex +
                                      PPS.binary +
                                      nation +
                                      party +
                                      log.seniority, 
                                    data = reduced.data)
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship_verystrong", "share_margin", "partisanship_verystrong:share_margin", "Constant")
  
  stargazer(model.4.all.ols.ctrls,
            model.4.presentation.ols.ctrls,
            model.4.ballot.ols.ctrls, 
            model.4.tenminute.ols.ctrls, 
            type = "html",
            title = "OLS regression of MPs' bill proposals (additional controls), 1964-2017",
            out = "./tableB4.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Constant"),
            keep.stat = c("rsq","n"),
            no.space = TRUE,
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark")),
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals (by type)}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B13)", "(B14)", "(B15)", "(B16)"),
            font.size = "small")
  
####################################################################
# Table B5 - Logistic regression of MPs' bill proposals, 1964-2017 #
#################################################################### 
  
  # Producing binary versions of dependent variables
  
  reduced.data$PMBs.total.binary <- ifelse(reduced.data$PMBs.total > 0, 1, 0)
  reduced.data$PMBs.presentation.binary <- ifelse(reduced.data$PMBs.presentation > 0, 1, 0)
  reduced.data$PMBs.ballot.binary <- ifelse(reduced.data$PMBs.ballot > 0, 1, 0)
  reduced.data$PMBs.tenminute.combined.binary <- ifelse(reduced.data$PMBs.tenminute.combined > 0, 1, 0)
  
  # Model B17 - Repeating Model 4 for all bills, with logit regression
  
  model.4.all.logit <- glm(PMBs.total.binary ~ 
                             partisanship_verystrong*share_margin + 
                             sitting_days + 
                             gov + 
                             retired + 
                             thirdparty.challenge +
                             age.elected*share_margin +
                             party_polarisation*share_margin, 
                           family = "binomial",
                           data = reduced.data)
  model.4.all.logit.R2 <- PseudoR2(model.4.all.logit, which = "McFadden")
  
  # Model B18 - Repeating Model 4 for presentation bills, with logit regression
  
  model.4.presentation.logit <- glm(PMBs.presentation.binary ~ 
                                      partisanship_verystrong*share_margin + 
                                      sitting_days + 
                                      gov + 
                                      retired + 
                                      thirdparty.challenge +
                                      age.elected*share_margin +
                                      party_polarisation*share_margin, 
                                    family = "binomial",
                                    data = reduced.data)
  model.4.presentation.logit.R2 <- PseudoR2(model.4.presentation.logit, which = "McFadden")
  
  # Model B19 - Repeating Model 4 for ballot bills, with logit regression
  
  model.4.ballot.logit <- glm(PMBs.ballot.binary ~
                                partisanship_verystrong*share_margin + 
                                sitting_days + 
                                gov + 
                                retired + 
                                thirdparty.challenge +
                                age.elected*share_margin +
                                party_polarisation*share_margin, 
                              family = "binomial",
                              data = reduced.data)
  model.4.ballot.logit.R2 <- PseudoR2(model.4.ballot.logit, which = "McFadden")
  
  # Model B20 - Repeating Model 4 for ten minute rule bills, with logit regression
  
  model.4.tenminute.logit <- glm(PMBs.tenminute.combined.binary ~
                                   partisanship_verystrong*share_margin + 
                                   sitting_days + 
                                   gov + 
                                   retired + 
                                   thirdparty.challenge +
                                   age.elected*share_margin +
                                   party_polarisation*share_margin, 
                                 family = "binomial",
                                 data = reduced.data)
  model.4.tenminute.logit.R2 <- PseudoR2(model.4.tenminute.logit, which = "McFadden")
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship_verystrong", "share_margin", "partisanship_verystrong:share_margin", "Constant")
  
  stargazer(model.4.all.logit, 
            model.4.presentation.logit, 
            model.4.ballot.logit, 
            model.4.tenminute.logit, 
            type = "html",
            title = "Logistic regression of MPs' bill proposals, 1964-2017",
            out = "./tableB5.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Constant"),
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                             c("Observations", "5,015", "5,015", "5,015", "5,015"),
                             c("Pseudo R\\textsuperscript{2}", 
                               round(model.4.all.logit.R2, digits = 3), 
                               round(model.4.presentation.logit.R2, digits = 3),
                               round(model.4.ballot.logit.R2, digits = 3),
                               round(model.4.tenminute.logit.R2, digits = 3))),
            omit.stat = c("n", "ll", "theta", "aic"),
            no.space = TRUE,
            dep.var.caption = "\\textit{Dependent Variable: Proposing at least one bill}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B17)", "(B18)", "(B19)", "(B20)"),
            font.size = "small")
  
##########################################################################
# Table B6 - Multilevel OLS regression of MPs' bill proposals, 1964-2017 #
########################################################################## 
  
  # Producing data with continuous variables rescaled
  
  data.rescaled <- transform(reduced.data,
                             partisanship_verystrong = scale(partisanship_verystrong),
                             share_margin = scale(share_margin),
                             sitting_days = scale(sitting_days),
                             age.elected = scale(age.elected),
                             party_polarisation = scale(party_polarisation))
  
  # Model B21 - Repeating Model 4 for all bills, with multilevel regression
  
  model.4.all.multilevel <- lmer(PMBs.total ~ 
                                   partisanship_verystrong*share_margin + 
                                   sitting_days + 
                                   gov + 
                                   retired + 
                                   thirdparty.challenge +
                                   age.elected*share_margin +
                                   party_polarisation*share_margin +
                                   (1 + share_margin | GE_date), 
                                 data = data.rescaled)
  
  # Model B22 - Repeating Model 4 for presentation bills, with multilevel regression
  
  model.4.presentation.multilevel <- lmer(PMBs.presentation ~ 
                                            partisanship_verystrong*share_margin + 
                                            sitting_days + 
                                            gov + 
                                            retired + 
                                            thirdparty.challenge +
                                            age.elected*share_margin +
                                            party_polarisation*share_margin +
                                            (1 + share_margin | GE_date), 
                                          data = data.rescaled)
  
  # Model B23 - Repeating Model 4 for ballot bills, with multilevel regression
  
  model.4.ballot.multilevel <- lmer(PMBs.ballot ~ 
                                      partisanship_verystrong*share_margin + 
                                      sitting_days + 
                                      gov + 
                                      retired + 
                                      thirdparty.challenge +
                                      age.elected*share_margin +
                                      party_polarisation*share_margin +
                                      (1 + share_margin | GE_date), 
                                    data = data.rescaled)
  
  # Model B24 - Repeating Model 4 for ten minute rule bills, with multilevel regression
  
  model.4.tenminute.multilevel <- lmer(PMBs.tenminute.combined ~ 
                                         partisanship_verystrong*share_margin + 
                                         sitting_days + 
                                         gov + 
                                         retired + 
                                         thirdparty.challenge +
                                         age.elected*share_margin +
                                         party_polarisation*share_margin +
                                         (1 + share_margin | GE_date), 
                                       data = data.rescaled)
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship_verystrong", "share_margin", "partisanship_verystrong:share_margin", "Constant")
  
  stargazer(model.4.all.multilevel, 
            model.4.presentation.multilevel, 
            model.4.ballot.multilevel, 
            model.4.tenminute.multilevel, 
            type = "html",
            title = "Multilevel OLS regression of MPs' bill proposals, 1964-2017",
            out = "./tableB6.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Constant"),
            keep.stat = c("n", "aic"),
            no.space = TRUE,
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals (by type)}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B21)", "(B22)", "(B23)", "(B24)"),
            font.size = "small",
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                             c("Random intercepts (Parliament)", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                             c("Random slopes (Margin)", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark")))
  
##########################################################################
# Table B7 - OLS model of MPs' bill proposals (clustered SEs), 1964-2017 #
########################################################################## 
  
  # Model B25 - Repeating Model 4 for all bills, with clustered SEs
  
  model.4.all.ols.clustered <- glm(PMBs.total ~ 
                                     partisanship_verystrong*share_margin + 
                                     sitting_days + 
                                     gov + 
                                     retired + 
                                     thirdparty.challenge +
                                     age.elected*share_margin +
                                     party_polarisation*share_margin, 
                                   data = reduced.data)
  
  all.clustered <- cluster.bs.glm(model.4.all.ols.clustered, data, ~ MP, ci.level = 0.95, boot.reps = 1000, seed = 555)
  
  all.clustered <- as.data.frame(all.clustered)
  names(all.clustered) <- c("p", "ci_lower", "ci_upper")
  all.clustered$se <- (all.clustered$ci_upper - all.clustered$ci_lower) / 3.92
  
  # Model B26 - Repeating Model 4 for presentation bills, with clustered SEs
  
  model.4.presentation.ols.clustered <- glm(PMBs.presentation ~
                                              partisanship_verystrong*share_margin +
                                              sitting_days +
                                              gov +
                                              retired +
                                              thirdparty.challenge +
                                              age.elected*share_margin +
                                              party_polarisation*share_margin,
                                            data = reduced.data)
  
  presentation.clustered <- cluster.bs.glm(model.4.presentation.ols.clustered, data, ~ MP, ci.level = 0.95, boot.reps = 1000, seed = 555)
  
  presentation.clustered <- as.data.frame(presentation.clustered)
  names(presentation.clustered) <- c("p", "ci_lower", "ci_upper")
  presentation.clustered$se <- (presentation.clustered$ci_upper - presentation.clustered$ci_lower) / 3.92
  
  # Model B27 - Repeating Model 4 for ballot bills, with clustered SEs
  
  model.4.ballot.ols.clustered <- glm(PMBs.ballot ~
                                        partisanship_verystrong*share_margin +
                                        sitting_days +
                                        gov +
                                        retired +
                                        thirdparty.challenge +
                                        age.elected*share_margin +
                                        party_polarisation*share_margin,
                                      data = reduced.data)
  
  ballot.clustered <- cluster.bs.glm(model.4.ballot.ols.clustered, data, ~ MP, ci.level = 0.95, boot.reps = 1000, seed = 555)
  
  ballot.clustered <- as.data.frame(ballot.clustered)
  names(ballot.clustered) <- c("p", "ci_lower", "ci_upper")
  ballot.clustered$se <- (ballot.clustered$ci_upper - ballot.clustered$ci_lower) / 3.92
  
  # Model B28 - Repeating Model 4 for ten minute rule bills, with clustered SEs
  
  model.4.tenminute.ols.clustered <- glm(PMBs.tenminute.combined ~
                                           partisanship_verystrong*share_margin +
                                           sitting_days +
                                           gov +
                                           retired +
                                           thirdparty.challenge +
                                           age.elected*share_margin +
                                           party_polarisation*share_margin,
                                         data = reduced.data)
  
  tenminute.clustered <- cluster.bs.glm(model.4.tenminute.ols.clustered, data, ~ MP, ci.level = 0.95, boot.reps = 1000, seed = 555)
  
  tenminute.clustered <- as.data.frame(tenminute.clustered)
  names(tenminute.clustered) <- c("p", "ci_lower", "ci_upper")
  tenminute.clustered$se <- (tenminute.clustered$ci_upper - tenminute.clustered$ci_lower) / 3.92
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship_verystrong", "share_margin", "partisanship_verystrong:share_margin", "Constant")
  
  stargazer(model.4.all.ols.clustered,
            model.4.presentation.ols.clustered,
            model.4.ballot.ols.clustered, 
            model.4.tenminute.ols.clustered, 
            type = "html",
            title = "OLS model of MPs' bill proposals (clustered SEs), 1964-2017",
            out = "./tableB7.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            se = list(all.clustered$se, presentation.clustered$se, ballot.clustered$se, tenminute.clustered$se),
            p = list(all.clustered$p, presentation.clustered$p, ballot.clustered$p, tenminute.clustered$p),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Constant"),
            omit.stat = c("n", "ll", "aic"),
            no.space = TRUE,
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                             c("Observations", "5,015", "5,015", "5,015", "5,015"),
                             c("R\\textsuperscript{2}", 
                               round((with(summary(model.4.all.ols.clustered), 1 - deviance/null.deviance)), digits = 3),
                               round((with(summary(model.4.presentation.ols.clustered), 1 - deviance/null.deviance)), digits = 3),
                               round((with(summary(model.4.ballot.ols.clustered), 1 - deviance/null.deviance)), digits = 3),
                               round((with(summary(model.4.tenminute.ols.clustered), 1 - deviance/null.deviance)), digits = 3))),
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals (by type)}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B25)", "(B26)", "(B27)", "(B28)"),
            font.size = "small")
  
#############################################################################
# Table B8 - OLS model of MPs' bill proposals (incl. time trend), 1964-2017 #
#############################################################################
  
  # generating time trend variable
  
  reduced.data$trend <- reduced.data$yr - min(reduced.data$yr)
  
  # Model B29 - Repeating Model 4 for all bills, with time trend
  
  model.4.all.ols.trend <- lm(PMBs.total ~ 
                                partisanship_verystrong*share_margin + 
                                sitting_days + 
                                gov + 
                                retired + 
                                thirdparty.challenge +
                                age.elected*share_margin +
                                party_polarisation*share_margin +
                                trend*share_margin,
                              data = reduced.data)
  
  # Model B30 - Repeating Model 4 for presentation bills, with time trend
  
  model.4.presentation.ols.trend <- lm(PMBs.presentation ~
                                         partisanship_verystrong*share_margin +
                                         sitting_days +
                                         gov +
                                         retired +
                                         thirdparty.challenge +
                                         age.elected*share_margin +
                                         party_polarisation*share_margin +
                                         trend*share_margin, 
                                       data = reduced.data)
  
  # Model B31 - Repeating Model 4 for ballot bills, with time trend
  
  model.4.ballot.ols.trend <- lm(PMBs.ballot ~
                                   partisanship_verystrong*share_margin +
                                   sitting_days +
                                   gov +
                                   retired +
                                   thirdparty.challenge +
                                   age.elected*share_margin +
                                   party_polarisation*share_margin +
                                   trend*share_margin, 
                                 data = reduced.data)
  
  # Model B32 - Repeating Model 4 for ten minute rule bills, with time trend
  
  model.4.tenminute.ols.trend <- lm(PMBs.tenminute.combined ~
                                      partisanship_verystrong*share_margin +
                                      sitting_days +
                                      gov +
                                      retired +
                                      thirdparty.challenge +
                                      age.elected*share_margin +
                                      party_polarisation*share_margin +
                                      trend*share_margin,
                                    data = reduced.data)
  
  # generating regression table of these four models as html file
  
  table.vars = c("partisanship_verystrong", "share_margin", "partisanship_verystrong:share_margin", "trend", "Constant")
  
  stargazer(model.4.all.ols.trend,
            model.4.presentation.ols.trend,
            model.4.ballot.ols.trend, 
            model.4.tenminute.ols.trend, 
            type = "html",
            title = "OLS regression of MPs' bill proposals (incl. time trend), 1964-2017",
            out = "./tableB8.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Partisanship", "Margin", "Partisanship*Margin", "Linear time trend", "Constant"),
            keep.stat = c("rsq","n"),
            no.space = TRUE,
            add.lines = list(c("Controls", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark")),
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals (by type)}",
            dep.var.labels.include = TRUE,
            dep.var.labels = c("\\underline{All Bills}", "\\underline{Presentation}", "\\underline{Ballot}", "\\underline{Ten Minute}"),
            model.numbers = FALSE,
            column.labels = c("(B29)", "(B30)", "(B31)", "(B32)"),
            font.size = "small")
  
#####################################################################################
# Figure C1 - Relationship between electoral security and bill proposals, 1964-2017 #
#####################################################################################
  
  # formatting variables for presentation in plot
  
  reduced.data$share_margin.1964 <- reduced.data$voteshare_margin
  reduced.data$share_margin.1966 <- reduced.data$voteshare_margin
  reduced.data$share_margin.1970 <- reduced.data$voteshare_margin
  reduced.data$share_margin.1974.oct <- reduced.data$voteshare_margin
  reduced.data$share_margin.1979 <- reduced.data$voteshare_margin
  reduced.data$share_margin.1983 <- reduced.data$voteshare_margin
  reduced.data$share_margin.1987 <- reduced.data$voteshare_margin
  reduced.data$share_margin.1992 <- reduced.data$voteshare_margin
  reduced.data$share_margin.1997 <- reduced.data$voteshare_margin
  reduced.data$share_margin.2001 <- reduced.data$voteshare_margin
  reduced.data$share_margin.2005 <- reduced.data$voteshare_margin
  reduced.data$share_margin.2010 <- reduced.data$voteshare_margin
  reduced.data$share_margin.2015 <- reduced.data$voteshare_margin
  
  # running separate bivariate regressions for each parliament
  
  model.1964 <- lm(PMBs.total ~
                     share_margin.1964,
                   data = reduced.data[reduced.data$yr==1964,])
  
  model.1966 <- lm(PMBs.total ~
                     share_margin.1966,
                   data = reduced.data[reduced.data$yr==1966,])
  
  model.1970 <- lm(PMBs.total ~
                     share_margin.1970,
                   data = reduced.data[reduced.data$yr==1970,])
  
  model.1974.oct <- lm(PMBs.total ~
                         share_margin.1974.oct,
                       data = reduced.data[(reduced.data$yr==1974 & reduced.data$mn=="October"),])
  
  model.1979 <- lm(PMBs.total ~
                     share_margin.1979,
                   data = reduced.data[reduced.data$yr==1979,])
  
  model.1983 <- lm(PMBs.total ~
                     share_margin.1983,
                   data = reduced.data[reduced.data$yr==1983,])
  
  model.1987 <- lm(PMBs.total ~
                     share_margin.1987,
                   data = reduced.data[reduced.data$yr==1987,])
  
  model.1992 <- lm(PMBs.total ~
                     share_margin.1992,
                   data = reduced.data[reduced.data$yr==1992,])
  
  model.1997 <- lm(PMBs.total ~
                     share_margin.1997,
                   data = reduced.data[reduced.data$yr==1997,])
  
  model.2001 <- lm(PMBs.total ~
                     share_margin.2001,
                   data = reduced.data[reduced.data$yr==2001,])
  
  model.2005 <- lm(PMBs.total ~
                     share_margin.2005,
                   data = reduced.data[reduced.data$yr==2005,])
  
  model.2010 <- lm(PMBs.total ~
                     share_margin.2010,
                   data = reduced.data[reduced.data$yr==2010,])
  
  model.2015 <- lm(PMBs.total ~
                     share_margin.2015,
                   data = reduced.data[reduced.data$yr==2015,])
  
  # plotting the coefficients from these models
  
  pdf("./figureC1.pdf", width = 4.5, height = 5)   
  multiplot(model.2015, model.2010, model.2005, model.2001, model.1997, model.1992,model.1987, 
            model.1983, model.1979, model.1974.oct, model.1970, model.1966, model.1964, 
            intercept = FALSE,
            innerCI = 1.645, # 90% CI
            outerCI = 0,
            lwdInner = 0.75,
            title = NULL,
            ylab = "Parliaments\n",
            xlab = "\nCoefficients",
            zeroColor="black",
            zeroLWD=0.5,
            pointSize = 2,
            newNames = c("share_margin.2015" = "2015-17",
                         "share_margin.2010" = "2010-15",
                         "share_margin.2005" = "2005-10",
                         "share_margin.2001" = "2001-05",
                         "share_margin.1997" = "1997-01",
                         "share_margin.1992" = "1992-97",
                         "share_margin.1987" = "1987-92",
                         "share_margin.1983" = "1983-87",
                         "share_margin.1979" = "1979-83",
                         "share_margin.1974.oct" = "1974-79",
                         "share_margin.1970" = "1970-74",
                         "share_margin.1966" = "1966-70",
                         "share_margin.1964" = "1964-66"))+
    scale_color_manual(values = c("black", "black", "black", "black", "black", "black", "black", 
                                  "black", "black", "black", "black", "black", "black"))+
    theme_classic()+
    theme(legend.position = "none",
          axis.title.x = element_text(face = "bold"),
          axis.title.y = element_text(face = "bold"),
          panel.border = element_rect(colour = "black", fill = NA, size = 0.7), # adds rectangle
          axis.line = element_blank())                                          # removes axis lines because they reinforce the rectangle
  dev.off()
  
###############################################################
# Table D1 - OLS regression of MPs' bill proposals, 1974-1983 #
###############################################################
  
  # Creating indicator of facing Liberal challenger
  
  reduced.data$liberal.challenge <- ifelse(reduced.data$challenger == "Liberal", 1, 0)
  
  # Modelling bill proposals in bivariate and multivariate models, both with FE
  
  fe.post.1974.liberals <- lm(PMBs.total ~
                                voteshare_margin*liberal.challenge +
                                GE_date,
                              data = reduced.data[(reduced.data$yr == 1974  | 
                                                     reduced.data$yr == 1979),])
  
  multivar.post.1974.liberals <- lm(PMBs.total ~
                                      voteshare_margin*liberal.challenge +
                                      gov +
                                      retired +
                                      GE_date,
                                    data = reduced.data[(reduced.data$yr == 1974 | 
                                                           reduced.data$yr == 1979),])

  # reporting these in a regression table
  
  table.vars = c("voteshare_margin", "liberal.challenge", "voteshare_margin:liberal.challenge", "Constant")
  
  stargazer(fe.post.1974.liberals, 
            multivar.post.1974.liberals, 
            type = "html",
            title = "OLS regression of MPs' bill proposals, 1974-1983",
            out = "./tableD1.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Margin", "Liberal challenger", "Margin*Liberal challenger", "Constant"),
            add.lines = list(c("Parliament FE", "\\checkmark", "\\checkmark"),
                             c("Controls", "", "\\checkmark")), 
            keep.stat = c("n", "rsq"),
            no.space = TRUE,
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals}",
            dep.var.labels.include = FALSE,
            model.numbers = FALSE,
            column.labels = c("(D1)", "(D2)"),
            font.size = "small")
  
####################################################
# Table D2 - OLS regression of MPs' bill proposals #
####################################################
  
  # Modelling bill proposals when including careerist variable
  
  careerist.multivariate <- lm(PMBs.total ~
                                 careerist +
                                 voteshare_margin +
                                 liberal.challenge +
                                 retired +
                                 GE_date,
                               data = reduced.data)
  
  careerist.multivariate.interaction <- lm(PMBs.total ~
                                             careerist*voteshare_margin +
                                             liberal.challenge +
                                             retired +
                                             GE_date,
                                           data = reduced.data)
  
  # Presenting results in a coefficient table
  
  table.vars = c("careerist", "voteshare_margin", "careerist:voteshare_margin", "Constant")
  
  stargazer(careerist.multivariate,
            careerist.multivariate.interaction,
            type = "html",
            title = "OLS regression of MPs' bill proposals",
            out = "./tableD2.html",
            keep = paste0("^", table.vars, "$"),
            order = paste0("^", table.vars, "$"),
            covariate.labels = c("Careerist", "Margin", "Careerist*Margin", "Constant"),
            keep.stat = c("rsq","n"),
            no.space = TRUE,
            add.lines = list(c("Parliament FE","\\checkmark", "\\checkmark"),
                             c("Controls", "\\checkmark", "\\checkmark")),
            dep.var.caption = "\\textit{Dependent Variable: Bill proposals}",
            dep.var.labels.include = FALSE,
            model.numbers = FALSE,
            column.labels = c("(D3)", "(D4)"))
  
#######################################################################################
# Figure D2 - Relationship between partisanship and standard deviation of marginality #
#######################################################################################
  
  # calculates standard deviation of marginality for each parliament
  
  margins.sd <- aggregate(reduced.data$voteshare_margin, by = list(reduced.data$yr, reduced.data$GE_date), FUN = sd)
  colnames(margins.sd) <- c("yr", "GE.date", "sd")
  
  # extracts partisanship measure for each parliament
  
  partisanship <- aggregate(reduced.data$partisanship_verystrong, by = list(reduced.data$yr, reduced.data$GE_date), FUN = mean)
  colnames(partisanship) <- c("yr", "GE.date", "partisanship")
  
  margins.sd <- merge(margins.sd, partisanship, by = c("GE.date", "yr"))
  rm(partisanship)
  
  # plots these two variables against each other
  
  pdf("./figureD2.pdf", width = 6, height = 4)  
  ggscatter(margins.sd, x = "partisanship", y = "sd",
            size = 0.5,
            add = "reg.line", conf.int = TRUE,
            cor.coef = TRUE, cor.method = "pearson")+
    theme_classic()+
    theme(axis.title.x = element_text(face = "bold"),
          axis.title.y = element_text(face = "bold"),
          panel.border = element_rect(colour = "black", fill = NA, size = 0.7), # adds rectangle
          axis.line = element_blank())+
    labs(x = "\n% very strong party identifiers",
         y = "s.d. of seat margins\n")
  dev.off()
  
###################################################################################
# Figure D3 - Private members' bills proposed daily in each Parliament, 1964-2017 #
###################################################################################

  # calculates daily number of private members' bills
  
  bills.descriptive <-  aggregate(data$PMBs.total, by = list(data$GE_date), FUN = sum)
  colnames(bills.descriptive) <- c("GE.date", "total.PMBs")
  
  sitting.days <- aggregate(data$sitting_days, by = list(data$GE_date), FUN = mean)
  colnames(sitting.days) <- c("GE.date", "sitting.days")
  
  bills.descriptive <- merge(bills.descriptive, sitting.days, by = "GE.date")
  rm(sitting.days)
  
  bills.descriptive$daily.PMBs <- bills.descriptive$total.PMBs / bills.descriptive$sitting.days
  
  bills.descriptive$GE.date <- as.Date(bills.descriptive$GE.date, format = '%m/%d/%Y')
  
  # plots this for every parliament in the data
  
  pdf("./figureD3.pdf", width = 6, height = 4)  
  ggplot(data = bills.descriptive, aes(x = GE.date, y = daily.PMBs))+
    geom_line(size = 0.7)+
    geom_point()+
    theme_classic()+
    xlab(NULL)+
    ylim(low = 0, high = 1)+
    ylab("PMBs proposed per sitting day\n")+
    theme(axis.title.y = element_text(face = "bold"),
          panel.border = element_rect(colour = "black", fill = NA, size = 0.7), # adds rectangle
          axis.line = element_blank())                                          # removes axis lines because they reinforce the rectangle
  dev.off()
  
##########################################################################################
  
  rm(list=ls())
